#include "graphics.h"

static SDL_Window *window = NULL;
static SDL_Renderer *renderer = NULL;
static colour_t *colourBuffer = NULL;
static SDL_Texture *colourBufferTexture = NULL;
static SDL_Rect mapRect;

static int WINDOW_WIDTH = 800;
static int WINDOW_HEIGHT = 600;

static int bufferWidth = 64;
static int bufferHeight = 64;

static double scaleX = 1;
static double scaleY = 1;

int mapScreenToMapCoord(int *x, int *y)
{
  int newX, newY;
  if (*x > mapRect.w || *y > mapRect.h)
    return 0;
  *x = *x * scaleX;
  *y = *y * scaleY;
  return 1;
}

int initialiseWindow(int dim, int w, int h)
{
  int fullScreenWidth,
      fullScreenHeight,
      maxDim;

  double rat;

  SDL_DisplayMode displayMode;

  bufferWidth = w * dim;
  bufferHeight = h * dim;

  if (SDL_Init(SDL_INIT_VIDEO) != 0)
  {
    fprintf(stderr, "Error initialising SDL.\n");
    return 0;
  }

  SDL_GetCurrentDisplayMode(0, &displayMode);
  fullScreenWidth = displayMode.w;
  fullScreenHeight = displayMode.h;

  // clipping rect
  mapRect.x = mapRect.y = 0;
  if (bufferWidth > bufferHeight)
  {
    mapRect.w = 800;
    rat = ((double)bufferHeight / (double)bufferWidth);
    mapRect.h = 800 * rat;
  }
  else
  {
    mapRect.h = 800;
    rat = ((double)bufferWidth / (double)bufferHeight);
    mapRect.w = 800 * rat;
  }

  // for converting mouse coords
  scaleX = (double)w / (double)mapRect.w;
  scaleY = (double)h / (double)mapRect.h;

  window = SDL_CreateWindow(NULL, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 800, 800, SDL_WINDOW_SHOWN);
  if (!window)
  {
    fprintf(stderr, "Error creating SDL window.\n");
    return 0;
  }

  renderer = SDL_CreateRenderer(window, -1, 0);
  if (!renderer)
  {
    fprintf(stderr, "Error creating SDL renderer.\n");
    return 0;
  }

  SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND);

  // allocate the total amount of bytes in memory to hold our colourBuffer
  colourBuffer = (colour_t *)malloc(bufferWidth * bufferHeight * sizeof(colour_t));
  colourBufferTexture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA32, SDL_TEXTUREACCESS_STREAMING, bufferWidth, bufferHeight);
  return 1;
}

void clearColourBuffer(colour_t colour)
{
  int x;
  for (x = 0; x < bufferWidth * bufferHeight; x++)
    colourBuffer[x] = colour;
}

void renderColourBuffer(void)
{
  SDL_UpdateTexture(colourBufferTexture, NULL, colourBuffer, (int)(bufferWidth * sizeof(colour_t)));
  SDL_RenderCopy(renderer, colourBufferTexture, NULL, &mapRect);
  SDL_RenderPresent(renderer);
}

void drawPixel(int x, int y, colour_t colour)
{
  colourBuffer[(bufferWidth * y) + x] = colour;
}
